#! /usr/bin/env bash
. ./scripts/devcontainer/_assert-in-container "$0" "$@"

set -euo pipefail

CHECK=255 # (0 mean check, 1 means format, 255 means error)
PRETTIER=0 # (0 means check prettier files, 1 means don't)
FSHARP=0 # (0 means check fsharp files, 1 means don't)
FILES=()

#######################
# --help
#######################
function print_help ()
{
	printf '%s\n' "All formatting across Dark"
	printf 'Usage: %s [check|format] <files|dirs...> [--help] \n' "$0"
	printf '\t%s\n' "check: Error if files are not formatted. No argument means check all files. Does not error if file is not supported."
	printf '\t%s\n' "format: Format file or dir. Formats all files with no argument. Does not error or format if file is not supported."
  printf '\t%s\n' "--fsharp-only: Only check fsharp files (fsi, fs)"
  printf '\t%s\n' "--prettier-only: Only check prettier files (js, css, etc)"
}

FILES=()

# check for flags
for val in "${@}"; do
  case "$val" in
    --help)
        print_help
        exit 0
        ;;
    --prettier-only)
        FSHARP=1
        ;;
    --fsharp-only)
        PRETTIER=1
        ;;
    check)
      CHECK=0
      ;;
    format)
      CHECK=1
      ;;
    *)
      FILES+=("$val")
      ;;
  esac
done

if [[ 255 -eq "$CHECK" ]]; then
  echo -e "usage:\n  ./scripts/formatting/format check [files]\n  ./scripts/formatting/format format [files]"
  exit 255
fi

#######################
# Parse rest of arguments
#######################
if [[ ${#FILES[@]} -eq 0 ]]; then
  FILES=(".")
fi

#######################
# functions
#######################
is_dir() {
  [[ -d "$1" ]]
}

is_fsharp() {
  [[ $1 == *.fs || $1 == *.fsi ]]
}

is_allowed() {
  [[ $1 == *.fs || $1 == *.fsi \
    || $1 == *.css || $1 == *.scss \
    || $1 == *.js || $1 == *.ts \
    || $1 == *.html
    || $1 == *.res || $1 == *.resi ]]
}

all_prettier_files() {
  find "$1" \
    \( -path ".git" \
    -o -path "backend" \
    -o -path "backend/static" \
    -o -path "./backend/static" \
    -o -path "backend/.paket" \
    -o -path "./backend/.paket" \
    -o -path "backend/Build" \
    -o -path "./backend/Build" \
    \) -prune -false \
    \
    -o -type f \
    \( -name "*.css" \
    -o -name "*.scss" \
    -o -name "*.js" \
    -o -name "*.ts" \
    -o -name "*.html" \
    \) -print0
}

all_fsharp_files() {
  find "$1" \
    \( -path ".git" \
    -o -path "backend" \
    -o -path "backend/.paket" \
    -o -path "./backend/.paket" \
    -o -path "backend/Build" \
    -o -path "./backend/Build" \
    \) -prune -false \
    \
    -o -type f \
    \( -name "*.fs" \
    -o -name "*.fsi" \
    \) -print
}

check_fantomas () {
  xargs fantomas --check
}

check_prettier () {
  xargs -0 npx prettier --list-different
}

format_fantomas() {
  xargs fantomas
}

format_prettier() {
  xargs -0 npx prettier --write
}

do_fantomas() {
  if [[ 0 -eq "$CHECK" ]]; then
    check_fantomas
  else
    format_fantomas
  fi
}

do_prettier() {
  if [[ 0 -eq "$CHECK" ]]; then
    check_prettier
  else
    format_prettier
  fi
}

# TODO sqlfmt for sql
# TODO add python
# TODO bash formatter

#######################
# action files/dirs
#######################
for i in "${FILES[@]}"; do
  if [[ -d "$i" ]]; then
    if [[ 0 -eq "$FSHARP" ]]; then
      all_fsharp_files $i | do_fantomas
    fi
    if [[ 0 -eq "$PRETTIER" ]]; then
      # CLEANUP there's no JS/CSS files at the moment
      # all_prettier_files "$i" | do_prettier
      echo "No JS files at the moment - reenable this"
    fi
  elif is_allowed "$i"; then
    if is_fsharp "$i"; then
      if [[ 0 -eq "$FSHARP" ]]; then
        echo "$i" | do_fantomas
      fi
    else
      if [[ 0 -eq "$PRETTIER" ]]; then
        echo "$i" | do_prettier
      fi
    fi
  else
    echo "ignored : $i"
  fi
done

